using System;
using System.IO;
using System.Text;
using System.Web;
using System.Globalization;
using System.Collections.Specialized;
using System.Collections.Generic;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

using RealDolmen.Helpers;

namespace RealDolmen.SharePoint.Helpers
{
    public enum SPUrlType
    {
        AbsoluteUrl,
        ServerRelativeUrl,
        SiteRelativeUrl
    }

    public class SPHelper
    {


        #region Url Of SPObject
        public static string GetAbsoluteUrl(SPList list)
        {
            SPWeb web = list.ParentWeb;
            SPSite site = web.Site;
            string url = SPUtility.GetFullUrl(site, list.DefaultViewUrl);
            //TryDisposeSite(site);
            //TryDisposeWeb(web);
            return url;
        }
        /// <summary>
        /// Gets the absolute url of the server WITHOUT trailing slash.
        /// </summary>
        /// <param name="web"></param>
        /// <returns></returns>
        public static string GetAbsoluteUrlOfServer(SPWeb web)
        {
            string absoluteUrl = web.Url;
            string serverRelativeUrl = web.ServerRelativeUrl;

            if (serverRelativeUrl.Length == 1)
                return absoluteUrl;
            else
                return absoluteUrl.Remove(absoluteUrl.LastIndexOf(serverRelativeUrl));
        }
        public static string GetAbsoluteUrlOfDisplayForm(SPListItem listItem)
        {
            return listItem.ParentList.ParentWeb.Site.MakeFullUrl(GetServerRelativeUrlOfDisplayForm(listItem));
        }
        public static string GetAbsoluteUrlOfEditForm(SPListItem listItem)
        {
            return listItem.ParentList.ParentWeb.Site.MakeFullUrl(GetServerRelativeUrlOfEditForm(listItem));
        }

        /// <summary>
        /// Gets the server relative url of the given web WITHOUT trailing slash.
        /// </summary>
        /// <param name="web"></param>
        /// <returns></returns>
        public static string GetServerRelativeUrl(SPWeb web, bool encodeUrlPath)
        {
            string urlToEncode = string.Empty;
            if (web != null)
            {
                urlToEncode = web.ServerRelativeUrl.TrimEnd(new char[] { '/' });
            }
            if (!encodeUrlPath)
            {
                return urlToEncode;
            }
            return (urlToEncode = SPHttpUtility.UrlPathEncode(urlToEncode, false, true));
        }
        public static string GetServerRelativeUrlOfDisplayForm(SPListItem listItem)
        {
            string serverRelativeUrl =
                listItem.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].ServerRelativeUrl;
            StringBuilder builder = new StringBuilder(serverRelativeUrl);
            builder.Append("?ID=");
            builder.Append(listItem.ID.ToString(CultureInfo.InvariantCulture).ToUpper(CultureInfo.InvariantCulture));

            return builder.ToString();
        }
        public static string GetServerRelativeUrlOfEditForm(SPListItem listItem)
        {
            string serverRelativeUrl =
                listItem.ParentList.Forms[PAGETYPE.PAGE_EDITFORM].ServerRelativeUrl;
            StringBuilder builder = new StringBuilder(serverRelativeUrl);
            builder.Append("?ID=");
            builder.Append(listItem.ID.ToString(CultureInfo.InvariantCulture).ToUpper(CultureInfo.InvariantCulture));

            return builder.ToString();
        }
        public static string GetServerRelativeUrlOfCurrentWeb(bool encodeUrlPath)
        {
            return GetServerRelativeUrl(SPContext.Current.Web, encodeUrlPath);
        }
        #endregion // Url Of SPObject

        #region SPObject From Url
        #region GetListItem
        /// <summary>
        /// Get the listitem from an absolute, server relative or site relative url.
        /// If the url is relative (server or site), the current site context will be used as a reference.
        /// </summary>
        /// <param name="url">The url can be absolute, server relative or site relative</param>
        /// <returns></returns>
        public static SPListItem GetListItem(string url)
        {
            return GetListItem(SPContext.Current.Web, url);
        }

        /// <summary>
        /// Get the listitem from an absolute, server relative or site relative url.
        /// You have to provide a site if the url is relative (server or site).
        /// </summary>
        /// <param name="web">Site which is used a reference in relative urls (server or site relative)</param>
        /// <param name="url">The url can be absolute, server relative or site relative</param>
        /// <returns></returns>
        public static SPListItem GetListItem(SPWeb web, string url)
        {
            SPListItem listItem = null;

            if (url.StartsWith("/"))
                url = string.Format("{0}{1}", SPHelper.GetAbsoluteUrlOfServer(web), url);
            else if (!url.Contains("://"))
                return GetListItemFromParentWeb(web, url);

            try
            {
                SPSite site = new SPSite(url);
                try
                {
                    SPWeb parentWeb = site.OpenWeb();
                    try
                    {
                        listItem = GetListItemFromParentWeb(parentWeb, url);
                    }
                    finally
                    {
                        TryDisposeWeb(parentWeb);
                    }
                }
                finally
                {
                    TryDisposeSite(site);
                }
            }
            catch { }
            return listItem;
        }
        /// <summary>
        /// Get a listitem from its parent web. The url can be an absolute, server relative or site relative url.
        /// </summary>
        /// <param name="parentWeb">Site to which the listItem belongs</param>
        /// <param name="url">The url can be absolute, server relative or site relative</param>
        /// <returns></returns>
        public static SPListItem GetListItemFromParentWeb(SPWeb parentWeb, string url)
        {
            SPListItem listItem = null;
            try
            {
                listItem = parentWeb.GetListItem(url);
            }
            catch { }

            if (listItem == null)
            {
                try
                {
                    SPList list = parentWeb.GetList(url);
                    int idx = url.IndexOf('?');
                    if (list != null && idx > 0)
                    {
                        NameValueCollection query = HttpUtility.ParseQueryString(url.Substring(idx + 1));
                        if (!string.IsNullOrEmpty(query["ID"]))
                            listItem = list.GetItemById(int.Parse(query["ID"]));
                    }
                }
                catch { }
            }

            return listItem;
        }
        #endregion // GetListItem

        #region GetListItems
        /// <summary>
        /// Get the listitems from its parent web. The url can be an absolute, server relative or site relative url and can include filterfields and rootfolder attributes
        /// </summary>
        /// <param name="parentWeb">Site to which the listItem belongs</param>
        /// <param name="url">The url can be absolute, server relative or site relative</param>
        /// <returns></returns>
        public static SPListItemCollection GetListItemsFromWeb(SPWeb parentWeb, string url, bool showFolders)
        {
            SPListItemCollection items = null;

            SPView view = GetView(parentWeb, url);

            if (view != null)
            {
                SPList list = view.ParentList;

                Dictionary<string, string> queryString = UrlPath.GetParametersFromQueryString(UrlPath.ExtractQueryString(url));
                Dictionary<string, string> filters = GetFiltersFromDictionary(queryString);
                SPQueryBuilder builder = new SPQueryBuilder();

                foreach (KeyValuePair<string, string> filter in filters)
                {
                    builder.AndEquals(filter.Key, filter.Value);
                }

                if (!string.IsNullOrEmpty(view.Query))
                    builder.And(view);

                // Now build the query object
                SPQuery query = builder.ToQuery();
                if (queryString.ContainsKey("RootFolder"))
                {
                    query.Folder = parentWeb.GetFolder(queryString["RootFolder"]);
                }

                string scopeFormat = "Scope=\"{0}\"";
                query.ViewAttributes = string.Format(scopeFormat, view.Scope);
                if (!showFolders)
                {
                    if (view.Scope == SPViewScope.RecursiveAll)
                        query.ViewAttributes = string.Format(scopeFormat, SPViewScope.Recursive);
                    else if (view.Scope == SPViewScope.Default)
                        query.ViewAttributes = string.Format(scopeFormat, SPViewScope.FilesOnly);
                }

                items = list.GetItems(query);
            }

            return items;
        }
        public static Dictionary<string, string> GetFiltersFromDictionary(Dictionary<string, string> parameters)
        {
            Dictionary<string, string> fieldDic = new Dictionary<string, string>();
            Dictionary<string, string> filterDic = new Dictionary<string, string>();

            foreach (KeyValuePair<string, string> pair in parameters)
            {
                string key = pair.Key;
                string value = pair.Value;

                if (value != null && key.Length > 10)
                {
                    if (key.StartsWith("FilterField"))
                    {
                        key = key.Substring(11);
                        fieldDic.Add(value, key);
                    }
                }
            }

            foreach (KeyValuePair<string, string> pair in fieldDic)
            {
                string value = parameters["FilterValue" + pair.Value];
                if (value != null)
                {
                    filterDic.Add(pair.Key, value);
                }
            }
            return filterDic;
        } 
        #endregion // GetListItems


        #region GetList
        /// <summary>
        /// Get the list from an absolute, server relative or site relative url.
        /// </summary>
        /// <param name="web"></param>
        /// <param name="url">The url can be absolute, server relative or site relative</param>
        /// <returns></returns>
        public static SPList GetList(SPWeb web, string url)
        {
            // TODO: parse for other sites too
            return GetListFromParentWeb(web, url);
        }

        public static SPList GetList(string absoluteUrl)
        {
            SPList list = null;
            try
            {
                SPSite site = new SPSite(absoluteUrl);
                try
                {
                    SPWeb web = site.OpenWeb();
                    try
                    {
                        list = GetList(web, absoluteUrl);
                    }
                    finally
                    {
                        TryDisposeWeb(web);
                    }
                }
                finally
                {
                    TryDisposeSite(site);
                }
            }
            catch { }
            return list;
        }

        /// <summary>
        /// Get a list from its parent web. The url can be an absolute, server relative or site relative url.
        /// </summary>
        /// <param name="parentWeb">Site to which the list belongs</param>
        /// <param name="url">The url can be absolute, server relative or site relative</param>
        /// <returns></returns>
        public static SPList GetListFromParentWeb(SPWeb parentWeb, string url)
        {
            SPList list = null;
            try
            {
                // If the url is site relative, make server relative
                if (!url.Contains("://") && !url.StartsWith(parentWeb.ServerRelativeUrl))
                {
                    url = SPUrlUtility.CombineUrl(parentWeb.ServerRelativeUrl, url);
                }

                // GetListFromUrl is deprecated
                list = parentWeb.GetList(url);
            }
            catch { }
            return list;

        } 
        #endregion // GetList

        #region GetView
        /// <summary>
        /// Get the view from an absolute, server relative or site relative url.
        /// </summary>
        /// <param name="web">Parent of the view</param>
        /// <param name="url">The url can be absolute, server relative or site relative</param>
        /// <returns></returns>
        public static SPView GetView(SPWeb web, string url)
        {
            SPView view = null;
            try
            {
                // If the url is site relative, make server relative
                if (!url.Contains("://") && !url.StartsWith(web.ServerRelativeUrl))
                {
                    url = SPUrlUtility.CombineUrl(web.ServerRelativeUrl, url);
                }

                try
                {
                    view = web.GetViewFromUrl(url);
                }
                catch { }

                if (view == null)
                {
                    SPList list = GetList(web, url);
                    view = list.DefaultView;
                }
            }
            catch { }
            return view;
        } 
        #endregion // GetView

        #region EnsureFolder
        public static SPFolder EnsureFolder(SPWeb web, string url)
        {
            return EnsureFolder(web, url, true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="web"></param>
        /// <param name="url">This url can be the full url with all segments. Also this can be server relative or web relative.</param>
        /// <param name="createAsListFolder">True if the folders to be created should also be viewable in their parent list or document library.</param>
        /// <returns></returns>
        public static SPFolder EnsureFolder(SPWeb web, string url, bool createAsListFolder)
        {
            SPFolder folder = web.GetFolder(url);

            if (!folder.Exists)
            {
                int idx = url.LastIndexOf('/');

                SPFolder parentFolder = (idx > 0) ? EnsureFolder(web, url.Remove(idx), createAsListFolder) : web.RootFolder;

                if (parentFolder != null)
                {
                    string name = url.Substring(idx + 1);

                    if (createAsListFolder && Guid.Empty != parentFolder.ParentListId)
                    {
                        SPList list = web.Lists[parentFolder.ParentListId];
                        SPListItem listItem = list.Items.Add(parentFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder, name);
                        if (list.EnableModeration)
                            listItem.ModerationInformation.Status = SPModerationStatusType.Approved;
                        listItem.Update();
                        folder = listItem.Folder;
                    }
                    else
                        folder = parentFolder.SubFolders.Add(name);
                }
                else
                    folder = null;
            }

            return folder;
        } 
        #endregion // EnsureFolder
        #endregion // SPObject From Url

        #region Misc SPObjects
        public static void UpdateCalendarViewStyleCollection(SPCalendarViewStyleCollection collection)
        {
            StringBuilder sb = new StringBuilder();
            foreach (SPCalendarViewStyle calendarViewStyle in collection)
            {
                sb.AppendFormat("<CalendarViewStyle Title='{0}' Type='{1}' Template='{2}' Sequence='{3}' Default='{4}' />",
                    SPHttpUtility.HtmlEncode(calendarViewStyle.Title),
                    SPHttpUtility.HtmlEncode(calendarViewStyle.Type),
                    SPHttpUtility.HtmlEncode(calendarViewStyle.Template),
                    calendarViewStyle.Sequence.ToString(),
                    calendarViewStyle.Default.ToString().ToUpper());
            }
            string xml = sb.ToString();
            xml = xml.Replace(">", "&gt;").Replace("<", "&lt;");

            if (!string.IsNullOrEmpty(xml))
            {
                WrapperObject wo = new WrapperObject(collection.View);
                wo.Invoke("SetInnerXmlForNode", "CalendarViewStyles", xml);
                try
                {
                    collection.View.Update();
                }
                catch
                {
                    System.Diagnostics.Trace.TraceError("SPHelper: Could not update view '{0}' with calendarviewstyles at '{1}'", collection.View.Title, collection.View.ServerRelativeUrl);
                }
            }
        }

        public static SPSchedule ScheduleFromString(string scheduleString)
        {
            SPSchedule schedule = SPSchedule.FromString(scheduleString);
            if (schedule == null)
            {
                DateTime occurence;
                if (DateTime.TryParse(scheduleString, out occurence))
                {
                    schedule = new SPOneTimeSchedule(occurence);
                }
            }
            return schedule;
        }

        public static SPList GetFirstListOf(SPWeb web, SPListTemplateType listTemplateType)
        {
            foreach (SPList list in web.Lists)
            {
                if (list.BaseTemplate == listTemplateType)
                    return list;
            }
            return null;
        }

        #region GetListTemplate
        public static SPListTemplate GetListTemplate(SPListTemplateCollection listTemplates, Guid featureId, int type)
        {
            foreach (SPListTemplate listTemplate in listTemplates)
            {
                if (listTemplate.FeatureId == featureId && (int)listTemplate.Type == type)
                    return listTemplate;
            }
            return null;
        }
        #endregion // GetListTemplate

        public static SPListTemplate GetListTemplate(SPList list)
        {
            SPWeb web = list.ParentWeb;

            SPListTemplate listTemplate = null;

            for (int i = 0; i < web.ListTemplates.Count && listTemplate == null; i++)
            {
                SPListTemplate tempListTemplate = web.ListTemplates[i];

                if (tempListTemplate != null &&
                    tempListTemplate.FeatureId == list.TemplateFeatureId &&
                    (int)tempListTemplate.Type == (int)list.BaseTemplate)
                {
                    listTemplate = tempListTemplate;
                }
            }

            return listTemplate;
        }

        public static void DeleteWeb(SPWeb web)
        {
            try
            {
                foreach (SPWeb subWeb in web.Webs)
                {
                    DeleteWeb(subWeb);
                }
            }
            catch { }

            web.Delete();
        }
        #endregion // Misc SPObjects

        #region Disposing Objects
        public static void TryDisposeWeb(SPWeb web)
        {
            if (web != null)
            {
                if (SPContext.Current != null)
                {
                    int hashContext = SPContext.Current.Web.GetHashCode();
                    int hash = web.GetHashCode();

                    Guid idContext = SPContext.Current.Web.ID;
                    Guid id = web.ID;

                    if (id != idContext || hash != hashContext)
                        web.Dispose();
                }
                else
                {
                    web.Dispose();
                }
            }
        }
        public static void TryDisposeSite(SPSite site)
        {
            if (site != null)
            {
                if (SPContext.Current != null)
                {
                    int hashContext = SPContext.Current.Site.GetHashCode();
                    int hash = site.GetHashCode();

                    Guid idContext = SPContext.Current.Site.ID;
                    Guid id = site.ID;

                    if (id != idContext || hash != hashContext)
                        site.Dispose();
                }
                else
                {
                    site.Dispose();
                }
            }
        }
        #endregion // Disposing Objects



        #region GetUser(s)

        public static SPPrincipal EnsurePrincipal(SPPrincipalInfo principal, SPWeb web)
        {
            if (principal.PrincipalType == SPPrincipalType.User || principal.PrincipalType == SPPrincipalType.SecurityGroup)
            {
                if (principal.PrincipalId < 0)
                {
                    web.SiteUsers.Add(principal.LoginName, principal.Email, principal.DisplayName, string.Empty);
                }

                return web.SiteUsers[principal.LoginName];
            }
            else if (principal.PrincipalType == SPPrincipalType.SharePointGroup)
            {
                if (principal.PrincipalId < 0)
                {
                    return null;
                }

                return web.SiteGroups[principal.LoginName];
            }

            return null;
        }

        public static List<SPPrincipal> EnsurePrincipals(List<SPPrincipalInfo> principalInfos, SPWeb web)
        {
            List<SPPrincipal> principals = new List<SPPrincipal>();

            foreach (SPPrincipalInfo principalInfo in principalInfos)
            {
                SPPrincipal principal = EnsurePrincipal(principalInfo, web);
                if (principal != null)
                    principals.Add(principal);
            }

            return principals;
        }

        public static SPPrincipal GetPrincipal(SPWeb web, SPPrincipalInfo info)
        {
            return GetPrincipal(web, info.LoginName);
        }
        public static SPPrincipal GetPrincipal(SPWeb web, string loginName)
        {
            SPPrincipal principal = null;

            try
            {
                principal = web.AllUsers[loginName];
            }
            catch { }

            try
            {
                if (principal == null)
                    principal = web.Groups[loginName];
            }
            catch { }

            try
            {
                if (principal == null)
                    principal = web.SiteGroups[loginName];
            }
            catch { }

            return principal;
        }
        public static SPPrincipal EnsureGroup(SPWeb web, string input)
        {
            return EnsureGroup(web, input, true);
        }
        public static SPPrincipal EnsureGroup(SPWeb web, string input, bool addToSite)
        {
            SPPrincipal principal = GetPrincipal(web, input);

            if (principal == null)
            {
                // web.Site should not be disposed
                web.SiteGroups.Add(input, web.Site.Owner, null, string.Empty);

                SPGroup group = web.SiteGroups[input];
                principal = group;
                if (addToSite)
                {
                    web.AssociatedGroups.Add(group);
                    web.Update();
                }
            }
            return principal;
        }
        public static SPUser GetUser(string strUser, SPWeb web)
        {
            if (web != null && !string.IsNullOrEmpty(strUser))
            {
                strUser = strUser.Trim();

                try
                {
                    // if it's no valid lookupfield, it'll throw an error
                    SPFieldLookupValue lookupUser = new SPFieldLookupValue(strUser);
                    return web.AllUsers.GetByID(lookupUser.LookupId);
                }
                catch { }

                try
                {
                    return web.AllUsers[strUser];
                }
                catch { }
            }
            return null;
        }

        #region GetPrincipals
        public static List<SPPrincipalInfo> GetPrincipals(SPWeb web, SPFieldLookupValueCollection collection)
        {
            return GetPrincipals(web, collection, SPPrincipalType.All);
        }
        public static List<SPPrincipalInfo> GetPrincipals(SPWeb web, SPFieldLookupValueCollection collection, SPPrincipalType scopes)
        {
            return GetPrincipals(web, collection, scopes, false);
        }
        public static List<SPPrincipalInfo> GetPrincipals(SPWeb web, SPFieldLookupValueCollection collection, SPPrincipalType scopes, bool recursively)
        {
            List<SPPrincipalInfo> principals = new List<SPPrincipalInfo>();

            foreach (SPFieldLookupValue lookupValue in collection)
            {
                principals.AddRange(SPHelper.GetPrincipals(web, lookupValue.LookupValue, scopes, recursively));
            }

            return principals;
        }

        public static List<SPPrincipalInfo> GetPrincipals(SPWeb web, string input)
        {
            return GetPrincipals(web, input, SPPrincipalType.All);
        }
        public static List<SPPrincipalInfo> GetPrincipals(SPWeb web, string input, SPPrincipalType scopes)
        {
            return GetPrincipals(web, input, scopes, false);
        }
        public static List<SPPrincipalInfo> GetPrincipals(SPWeb web, string input, SPPrincipalType scopes, bool recursively)
        {
            bool reached; int max = 500;
            List<SPPrincipalInfo> resultPrincipals = new List<SPPrincipalInfo>();
            SPPrincipalInfo principal = null;

            //IList<SPPrincipalInfo> principals = SPUtility.SearchPrincipals(web, input, scopes, SPPrincipalSource.All, null, 200, out reached);
            try
            {
                principal = SPUtility.ResolvePrincipal(web, input, scopes, SPPrincipalSource.All, null, false);
            }
            catch { }

            //foreach (SPPrincipalInfo principal in principals)
            //{
            if (principal != null && principal.PrincipalType != SPPrincipalType.None)
            {
                if (principal.PrincipalType != SPPrincipalType.User && recursively)
                {
                    resultPrincipals.AddRange(GetPrincipalsInGroupRecursively(web, principal.LoginName, max, out reached));
                }
                else
                    resultPrincipals.Add(principal);
            }
            //}

            return resultPrincipals;
        }

        private static List<SPPrincipalInfo> GetPrincipalsInGroupRecursively(SPWeb web, string input, int max, out bool reached)
        {
            List<SPPrincipalInfo> resultPrincipals = new List<SPPrincipalInfo>();

            SPPrincipalInfo[] principals =
                SPUtility.GetPrincipalsInGroup(web, input, max, out reached);

            foreach (SPPrincipalInfo principal in principals)
            {
                if (principal.PrincipalType == SPPrincipalType.User)
                    resultPrincipals.Add(principal);
                else if (principal.PrincipalType != SPPrincipalType.None)
                    resultPrincipals.AddRange(GetPrincipalsInGroupRecursively(web, principal.LoginName, max, out reached));
            }

            return resultPrincipals;
        }

        #endregion // GetPrincipals

        public static List<SPUser> GetUsers(string usersString, SPWeb web)
        {
            if (web != null && !string.IsNullOrEmpty(usersString))
            {
                usersString = usersString.Trim();

                try
                {
                    // if it's no valid lookupfield, it'll throw an error
                    SPFieldUserValueCollection fieldUsers =
                        new SPFieldUserValueCollection(web, usersString);

                    if (fieldUsers.Count > 0)
                    {
                        return fieldUsers.ConvertAll<SPUser>(delegate(SPFieldUserValue userValue)
                        {
                            return userValue.User;
                        });
                    }
                }
                catch { }

                try
                {
                    string[] strUsers = usersString.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);

                    foreach (string strUser in strUsers)
                    {
                        SPUser user = GetUser(strUser, web);
                        if (user != null)
                        {
                            List<SPUser> users = new List<SPUser>();
                            users.Add(user);
                            return users;
                        }
                    }
                }
                catch { }
            }
            return null;
        }

        public static List<SPUser> ExtractUsers(string strUsers, string separator, SPWeb web)
        {
            List<SPUser> users = new List<SPUser>();

            string[] tmpStrUsers = strUsers.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string tmp in tmpStrUsers)
            {
                List<SPUser> tmpUsers = GetUsers(tmp, web);

                if (tmpUsers != null)
                    users.AddRange(tmpUsers);
            }

            return users;
        }
        #endregion // GetUser(s)

        #region Permissions
        public static SPBasePermissions ParsePermissions(string strPerms)
        {
            SPBasePermissions emptyMask = SPBasePermissions.EmptyMask;
            if (!string.IsNullOrEmpty(strPerms))
            {
                char[] separator = new char[] { ',' };
                foreach (string str in strPerms.Split(separator))
                {
                    if (!string.IsNullOrEmpty(str))
                        emptyMask |= ParsePermission(str);
                }
            }
            return emptyMask;
        }

        public static SPBasePermissions ParsePermission(string strPerm)
        {
            return (SPBasePermissions)Enum.Parse(typeof(SPBasePermissions), strPerm);
        }
        #endregion // Permissions

        #region Security
        public static bool GiveRoleTo(ISecurableObject securableObject, string strPrincipal, string strRoleDefinition, SPWeb web)
        {
            // TODO: should be checked for security: can it work for regular users?

            SPPrincipal principal = SPHelper.EnsureGroup(web, strPrincipal);
            SPRoleDefinition roleDefinition = SPHelper.GetRoleDefinition(web, strRoleDefinition);

            // The permission level exist, try to add it the role assignment
            if (roleDefinition != null && principal != null)
            {
                // Get the role assignment for the principal on the securable object
                SPRoleAssignment roleAssignment = SPHelper.GetRoleAssignment(securableObject.RoleAssignments, principal);
                securableObject.RoleAssignments.Add(roleAssignment);

                roleAssignment.RoleDefinitionBindings.Add(roleDefinition);

                return true;
            }
            return false;
        }

        public static SPRoleDefinition GetRoleDefinition(SPWeb myweb, string name)
        {
            SPRoleDefinition roleDefinition = null;

            try
            {
                roleDefinition = myweb.RoleDefinitions[name];
            }
            catch { }

            return roleDefinition;
        }

        /*
         * Get the role assignment of the principal on the collection or create a new role assignment
         */
        public static SPRoleAssignment GetRoleAssignment(SPRoleAssignmentCollection roleCollection, SPPrincipal principal)
        {
            SPRoleAssignment roleAssignment = null;

            try
            {
                roleAssignment = roleCollection.GetAssignmentByPrincipal(principal);
            }
            catch { }

            if (roleAssignment == null)
                roleAssignment = new SPRoleAssignment(principal);

            return roleAssignment;
        }



        public static ISecurableObject GetSecurableObject(SPWeb web, string objectServerRelativeUrl)
        {
            //TODO: have an own implementation someday
            WrapperType wt = new WrapperType(typeof(SPUtility));
            object securableObject = wt.Invoke("GetIsecurableObjectFromUrl", web, objectServerRelativeUrl);
            return securableObject as ISecurableObject;
        }

        public static bool CompareSecurableObjects(ISecurableObject secObj1, ISecurableObject secObj2)
        {
            if (secObj1 is SPList && secObj2 is SPList)
            {
                return (secObj1 as SPList).ID == (secObj2 as SPList).ID;
            }
            else if (secObj1 is SPListItem && secObj2 is SPListItem)
            {
                return (secObj1 as SPListItem).UniqueId == (secObj2 as SPListItem).UniqueId;
            }
            else if (secObj1 is SPWeb && secObj2 is SPWeb)
            {
                return (secObj1 as SPWeb).ID == (secObj2 as SPWeb).ID;
            }
            return false;
        }
        #endregion // Security



        #region TryConvert
        public static bool TryGetListFieldId(string internalName, SPList list, out Guid fieldId)
        {

            try
            {
                // Try the internal name.
                fieldId = list.Fields.GetFieldByInternalName(internalName).Id;
                return true;
            }
            catch { }

            try
            {
                // Try the display name.
                fieldId = list.Fields[internalName].Id;
                return true;
            }
            catch { }


            fieldId = default(Guid);
            return false;
        }

        public static object TryConvertToGuid(object field)
        {
            try
            {
                return new Guid(field.ToString());
            }
            catch { }

            return field;
        }
        #endregion // TryConvert

        #region SendEmail
        public static bool SendEmail(string to, string subject, string body)
        {
            return SendEmail(to, subject, body, SPContext.Current.Web);
        }
        public static bool SendEmail(string to, string subject, string body, SPWeb web)
        {
            if (body != null)
            {
                StringDictionary messageHeaders = new StringDictionary();
                messageHeaders["to"] = to;
                messageHeaders["from"] = web.Site.WebApplication.OutboundMailSenderAddress;
                messageHeaders["subject"] = subject;

                return SPUtility.SendEmail(
                    web,
                    messageHeaders,
                    body);
            }
            return false;
        }

        public static bool SendEmail(string to, string cc, string bcc, string subject, string body)
        {
            return SendEmail(to, cc, bcc, subject, body, SPContext.Current.Web);
        }

        public static bool SendEmail(string to, string cc, string bcc, string subject, string body, SPWeb web)
        {
            if (body != null && to != null)
            {
                StringDictionary messageHeaders = new StringDictionary();

                if (!string.IsNullOrEmpty(cc))
                    messageHeaders["cc"] = cc;

                if (!string.IsNullOrEmpty(bcc))
                    messageHeaders["bcc"] = bcc;

                messageHeaders["to"] = to;
                messageHeaders["from"] = web.Site.WebApplication.OutboundMailSenderAddress;
                messageHeaders["subject"] = subject;

                return SPUtility.SendEmail(
                    web,
                    messageHeaders,
                    body);
            }
            return false;
        }

        #endregion // SendEmail

        #region CultureInfo
        public static CultureInfo GetCultureInfo(SPWeb web)
        {
            CultureInfo languageCulture = null;
            int language = (int)web.Language;
            try
            {
                languageCulture = new CultureInfo(language, false);
            }
            catch (Exception)
            {
            }
            return languageCulture;
        }
        public static CultureInfo CurrentCultureInfo
        {
            get
            {
                if (SPContext.Current == null)
                    return CultureInfo.InvariantCulture;
                else
                    return GetCultureInfo(SPContext.Current.Web);
            }
        }
        #endregion // CultureInfo

        #region Upload File
        public enum FileUploadMode
        {
            Overwrite,
            DoNothing,
            ReturnCurrent
        }

        public static SPFile UploadFileTo(HttpPostedFile postedFile, string documentLibraryUrl, FileUploadMode modeDestinationAlreadyExists)
        {
            return UploadFileTo(postedFile, documentLibraryUrl, string.Empty, modeDestinationAlreadyExists);
        }

        public static SPFile UploadFileTo(HttpPostedFile postedFile, string documentLibraryUrl, string filename, FileUploadMode modeDestinationAlreadyExists)
        {
            SPFile file = null;
            if (postedFile.ContentLength > 0)
            {
                if (string.IsNullOrEmpty(filename))
                    filename = Path.GetFileName(postedFile.FileName);

                using (SPSite site = new SPSite(documentLibraryUrl))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        SPList list = web.GetListFromUrl(documentLibraryUrl);
                        SPDocumentLibrary lib = (SPDocumentLibrary)list;
                        if (lib != null)
                        {
                            try
                            {
                                bool overwrite = (modeDestinationAlreadyExists == FileUploadMode.Overwrite);
                                file = lib.RootFolder.Files.Add(filename, postedFile.InputStream, overwrite);
                            }
                            catch { }

                            if (file == null && modeDestinationAlreadyExists == FileUploadMode.ReturnCurrent)
                            {
                                try
                                {
                                    file = lib.RootFolder.Files[filename];
                                }
                                catch { }
                            }
                        }
                    }
                }
            }
            return file;
        }
        #endregion // Upload File
    }
}
